#include<stdio.h>
#include<stdlib.h>
#include<at89c51ed2.h>
#include <mcs51reg.h>
#include<ctype.h>
#include<math.h>




void _sdcc_external_startup() {
	AUXR|=0x0C;	//XRAM 1024 bytes activated
	TMOD|=0x20;		//Timer 1 Mode 2
	TH1=0xFD;		// Timer Value 253
	SCON = 0x50; // SCON: mode 1, 8-bit UART, enable rcvr
	PCON|=0x80;		// double baud rate to 19200
	TR1 = 1; // TR1: timer 1 run
	TI = 1;	//set TI flag for putchar sequence
	RI = 0;	
	
}
int modeS=0; //X2 / X1 Mode Identifier
int timer=0; //stores the execution time in ms



	
//timer 0 overflow ISR
void timer0_overflow(void) __interrupt (1) 
{
	
		if (modeS==1){ //X2 mode Count - Timer Overflows every 2000 Machine Cycles ie every 1ms in X2 Mode
		TH0=0xF8;
		TL0=0x30;
					}
		else{ //X1 Mode Count-- Timer Overflows every 1000 Machine Cycles ie every 1ms in X1 Mode
		TH0=0xFC;
		TL0=0x18;
		}

	__critical(timer++); //increments every 1ms of program run


}



void main()
{
	
	
	
	//Poisson Distribution: e^-a*a^k/ k!
//The compiler will use floating point support automatically every time a floating point operation is required.
	
	float a;
	xdata float k;
	xdata float * exponential;
	xdata float *power;
	xdata float  *answer;
	int i;
	
	char val;
	
	exponential=malloc(100);
	power=malloc(100);
	answer=malloc(100);
	
	TMOD|=0x01; //timer 0, 16-bit
	EA=1; //set Global Interrupt
	ET0=1; //set Timer 0 Overflow Interrupt
	
	
while(1)
	{
			
			printf("\r\nPress 1 for Normal Mode, 2 for X2 Mode\r\n");
			val = getchar();    //take user character input
			
			//putchar(val); //echo characters back
			
			val=toupper(val); //convert to upper characters

		switch(val){
			
			case '1':		
							 	if (modeS==0){
						 			printf("\r\nAlready in Normal Mode");
						 		}
						 		else{
						 			modeS=0; //x2 mode identifer bit cleared
						 			CKCKON0=0x00; //disable X2 mode		
						 			printf_tiny("\r\nNormal Mode ON\r\n");//X mode	
						 			 		
						 		}	
						 		TH0=0xFC;
								TL0=0x18; 			 
								 break;
			
			
			
			case '2':			if(modeS==1){
									printf("Already in X2 Mode");
								}
								else{
								modeS=1; //x2 mode identifier bit set
						 		CKCKON0=0x05; //PCAX2=12clk,timer 0 increments every 6 Osc. Period
						 		printf_tiny("X2 Mode ON\r\n");//X mode	
								}
								TH0=0xF8;
								TL0=0x30; 
						 		break;	
		}
								 
								
	
	timer=0;
	
	a=1.23457; //test floating point values
	k=5.221;
	TR0=1; //start the counter to measure program execution time
	
	for(i=0;i<50;i++){
		exponential[i]=expf((-a)); //exponential=e^(-a)
		power[i]=powf(a,k);// power=a^k
		answer[i]=(exponential[i])*(power[i]); //answer=exponential*power, here the floating point library is used by the compiler
		a=a+0.012;
		k=k+0.001245;
		}
	
		
	
		
	TR0=0; //stop the counter	
	printf_tiny("\r\nCalculations Done!");
	

	
	
	printf("\r\nExecution Time: %d ms",timer);
	}
}


